/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 中科软支付平台
 * 创建日期 : 2016年12月13日
 * 修改历史 : 
 *     1. [2016年12月13日]创建文件 by liuyujia
 */
package com.sinosoft.sinopay.web.weixinpay.web.controller;

import java.io.IOException;
import java.math.BigDecimal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSON;
import com.sinosoft.sinocloud.common.biz.service.ReportLogService;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_DEALTYPE;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_REPORTTYPE;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_STATE;
import com.sinosoft.sinocloud.common.dto.ReportLogDTO;
import com.sinosoft.sinocloud.platform.base.SinoBaseController;
import com.sinosoft.sinocloud.platform.common.exception.biz.BizDataErrException;
import com.sinosoft.sinocloud.platform.common.exception.biz.IllegalRequestException;
import com.sinosoft.sinocloud.platform.common.exception.biz.SinoBizException;
import com.sinosoft.sinocloud.platform.common.exception.checked.RepeatRequestException;
import com.sinosoft.sinocloud.platform.common.exception.system.SinoSystemException;
import com.sinosoft.sinocloud.platform.common.util.SecurityUtil;
import com.sinosoft.sinopay.payrules.config.ENUM_PAY_TYPE;
import com.sinosoft.sinopay.payrules.dto.MerchantCheckDTO;
import com.sinosoft.sinopay.payrules.facade.PayWayFacade;
import com.sinosoft.sinopay.paytrade.dto.PaymentRequestDTO;
import com.sinosoft.sinopay.web.weixinpay.biz.config.ENUM_REPORT_BIZTYPE;
import com.sinosoft.sinopay.web.weixinpay.biz.config.WechatPaymentConstants;
import com.sinosoft.sinopay.web.weixinpay.biz.service.PaymentWechatService;
import com.sinosoft.sinopay.web.weixinpay.biz.service.WechatSecurityService;
import com.sinosoft.sinopay.web.weixinpay.config.ENUM_PAY_RET;
import com.sinosoft.sinopay.web.weixinpay.dto.WechatEntryRequsetDTO;
import com.sinosoft.sinopay.web.weixinpay.dto.WechatEntryResponseDTO;

/**  
 * 【微信支付下订单请求入口Controller】
 * @author liuyujia
 * @date 2016年12月13日 下午4:02:19 
 * @version V1.0  
 */
@Controller
@RequestMapping("/sinopay/wechatOrderPay")
public class WechatOederPayController extends SinoBaseController{

	@Autowired
	private PaymentWechatService paymentWechatService;
	@Autowired
	private WechatSecurityService wechatSecurityService;
	@Autowired
    private ReportLogService reportLogService;
	@Autowired
	private PayWayFacade payWayFacade;
	/** 请求超时时间 */
//    private Long overTime = 600000l;
   
    @RequestMapping(value = "wechatRequest.do",method = RequestMethod.POST)
	public void getWechatOrderUrl(HttpServletRequest request, HttpServletResponse response){
    	logger.info("支付平台微信支付下订单操作start......");
		//1.接收请求参数
		String tPayData = request.getParameter("pay_data");
		logger.info("请求支付密文为："+tPayData);
    	String tSignMsg = request.getParameter("sign_msg");
    	logger.info("请求支付签名为："+tSignMsg);
    	String tRequestIp = getRemortIP(request);
    	ReportLogDTO tReportLogDTO = new ReportLogDTO();//定义日志对象
    	//返回信息定义
    	WechatEntryResponseDTO wechatEntryResponseDTO = new WechatEntryResponseDTO();
		try{
			//2.请求信息解密
			String tDecodeData = SecurityUtil.aesDecrypt(tPayData, WechatPaymentConstants.REPORT_ENCRY_KEY);
			logger.info("请求报文为："+tDecodeData);
			//3.解析报文
			logger.info("解析报文开始......");
			WechatEntryRequsetDTO tWechatEntryRequsetDTO = JSON.parseObject(tDecodeData, WechatEntryRequsetDTO.class);
			//4.验证请求合法性
			//4.1 验证签名合法性
			logger.info("验证签名合法性开始......");
			String tMerchantCode = tWechatEntryRequsetDTO.getMerchantCode();
			wechatSecurityService.checkMerchantSignValid(tMerchantCode, tWechatEntryRequsetDTO, tSignMsg);
			//4.2 验证请求IP合法性
			logger.info("验证请求IP合法性开始......");
			wechatSecurityService.checkRequestIpValid(tRequestIp);
			//4.3 调用规则服务，进行支付规则校验
			MerchantCheckDTO merchantCheckDTO = new MerchantCheckDTO();
			merchantCheckDTO.setMerchantCode(tWechatEntryRequsetDTO.getMerchantCode());
			merchantCheckDTO.setPayAmount(tWechatEntryRequsetDTO.getPayAmount());
			merchantCheckDTO.setPayType(ENUM_PAY_TYPE.WXPAY.code());//微信支付
			//TODO  支付规则校验
			logger.info("支付规则校验开始......");
			wechatSecurityService.checkMerchantRules(merchantCheckDTO);
			//5.生成报文日志对象
			tReportLogDTO.setBusinessType(ENUM_REPORT_BIZTYPE.PAY_ORDER_REQ.code());
			tReportLogDTO.setSourceCode(tWechatEntryRequsetDTO.getMerchantCode());
			tReportLogDTO.setRequestIp(tRequestIp);
			tReportLogDTO.setRequestXml(tDecodeData);
			tReportLogDTO.setReportType(ENUM_REPORTLOG_REPORTTYPE.RECEIVE.code());
			tReportLogDTO.setSerialNo(tWechatEntryRequsetDTO.getSerialNo());
			tReportLogDTO.setOrderBizNo(tWechatEntryRequsetDTO.getBizNo());
			tReportLogDTO.setDealType(ENUM_REPORTLOG_DEALTYPE.SYNC_DEAL.code());
			tReportLogDTO.setDescription(tWechatEntryRequsetDTO.getTransDesc());
			tReportLogDTO.setCallbackUrl("");
			//6.校验订单重复性
			logger.info("校验订单重复性开始......");
			String tSerialNo = tWechatEntryRequsetDTO.getSerialNo();
			String tPayAmountStr =  tWechatEntryRequsetDTO.getPayAmount().setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
			wechatSecurityService.checkRepeatRequest(tMerchantCode,tSerialNo);
			//7.生成支付URL
			logger.info("生成支付URL开始......");
			String payUrl = paymentWechatService.dealWechatPayRequest(tWechatEntryRequsetDTO);
			
			//8.返回支付地址
			logger.info("返回支付地址："+payUrl);
			tReportLogDTO.setState(ENUM_REPORTLOG_STATE.SUCC.code());
			wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_SUCCESS.code());
			wechatEntryResponseDTO.setRetMsg(ENUM_PAY_RET.PAY_RET_SUCCESS.desc());
			wechatEntryResponseDTO.setWechatMainUrl(payUrl);
		}
		catch(BizDataErrException ex){
			logger.error(ex.getStackTrace());
			wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg(ex.getMessage());
			tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
			tReportLogDTO.setDescription(ex.getMessage());
		}
		catch(RepeatRequestException ex){
    		logger.error(ex.getStackTrace());
	     	tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
	     	tReportLogDTO.setDescription(ex.getMessage());
	     	wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg(ex.getMessage());
    	}
    	catch(IllegalRequestException ex){
    		logger.error(ex.getStackTrace());
	     	tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
	     	tReportLogDTO.setDescription(ex.getMessage());
	     	wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg("非法支付请求！");
    	}
    	catch(SinoBizException ex){
    		logger.error(ex.getStackTrace());
	     	tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
	     	tReportLogDTO.setDescription(ex.getMessage());
	     	wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg(ex.getMessage());
    	}
    	catch(SinoSystemException ex){
    		logger.error(ex.getStackTrace());
	     	tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
	     	tReportLogDTO.setDescription(ex.getMessage());
	     	wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg("系统异常，请联系管理员!");
    	}
    	catch(Exception ex){
    		logger.error(ex.getStackTrace());
	     	tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
	     	tReportLogDTO.setDescription(ex.getMessage());
	     	wechatEntryResponseDTO.setRetCode(ENUM_PAY_RET.PAY_RET_FAIL.code());
			wechatEntryResponseDTO.setRetMsg("系统未知异常，请联系管理员!");
    	}
		finally{
    		//8.持久化报文
			try {
//				response.setContentType("text/html");
				response.setCharacterEncoding("UTF-8");
				response.setHeader("Content-type", "text/html;charset=UTF-8");
				response.getWriter().print(JSON.toJSONString(wechatEntryResponseDTO));
			} catch (IOException e) {
				logger.error(e.getStackTrace());
			}
    	}
	}

	/**
	 * 获取请求IP地址
	 * @param request
	 * @return
	 */
	private String getRemortIP(HttpServletRequest request) {
		if (request.getHeader("x-forwarded-for") == null) {
			return request.getRemoteAddr();
		}
		return request.getHeader("x-forwarded-for");
	}
}
